#ifndef ALARMMANAGER_H
#define ALARMMANAGER_H

#include <QObject>
#include <QList>
#include <QDateTime>
#include <QMutex>
#include <QJsonObject>
#include <QJsonArray>
#include "core/DataPoint.h"

namespace ModbusPlexLink {

class ChannelManager;
class Channel;

/**
 * @brief 报警类型枚举
 */
enum class AlarmType {
    HighLimit,      // 高限报警
    LowLimit,       // 低限报警
    HighHighLimit,  // 高高限报警
    LowLowLimit,    // 低低限报警
    ValueChange,    // 值变化报警
    DataQuality,    // 数据质量报警
    ConnectionLost, // 连接丢失报警
    Custom          // 自定义报警
};

/**
 * @brief 报警优先级
 */
enum class AlarmPriority {
    Low = 0,
    Medium = 1,
    High = 2,
    Critical = 3
};

/**
 * @brief 报警状态
 */
enum class AlarmState {
    Active,      // 激活
    Acknowledged,// 已确认
    Cleared      // 已清除
};

/**
 * @brief 报警规则
 */
struct AlarmRule {
    QString id;                  // 规则ID
    QString name;                // 规则名称
    bool enabled;                // 是否启用
    QString channelName;         // 通道名称
    QString tagName;             // 标签名称
    AlarmType type;              // 报警类型
    AlarmPriority priority;      // 优先级

    // 阈值
    double highLimit;            // 高限
    double lowLimit;             // 低限
    double highHighLimit;        // 高高限
    double lowLowLimit;          // 低低限
    double deadband;             // 死区

    // 延时
    int delaySeconds;            // 延时秒数（避免误报）

    // 消息
    QString message;             // 报警消息模板

    AlarmRule()
        : enabled(true), type(AlarmType::HighLimit), priority(AlarmPriority::Medium),
          highLimit(100.0), lowLimit(0.0), highHighLimit(120.0), lowLowLimit(-10.0),
          deadband(1.0), delaySeconds(0) {}

    // 序列化
    QJsonObject toJson() const;
    static AlarmRule fromJson(const QJsonObject& json);
};

/**
 * @brief 报警事件
 */
struct AlarmEvent {
    QString id;                  // 事件ID（UUID）
    QString ruleId;              // 规则ID
    QString ruleName;            // 规则名称
    AlarmType type;              // 报警类型
    AlarmPriority priority;      // 优先级
    AlarmState state;            // 状态

    QString channelName;         // 通道名称
    QString tagName;             // 标签名称
    QVariant value;              // 触发值
    QString message;             // 报警消息

    QDateTime activeTime;        // 激活时间
    QDateTime acknowledgedTime;  // 确认时间
    QDateTime clearedTime;       // 清除时间
    QString acknowledgedBy;      // 确认人

    AlarmEvent()
        : type(AlarmType::HighLimit), priority(AlarmPriority::Medium),
          state(AlarmState::Active) {}

    // 序列化
    QJsonObject toJson() const;
    static AlarmEvent fromJson(const QJsonObject& json);
};

/**
 * @brief 报警管理器
 *
 * 功能：
 * - 报警规则管理（增删改查）
 * - 实时监控数据点，触发报警
 * - 报警事件记录
 * - 报警确认与清除
 * - 报警历史查询
 * - 报警统计
 */
class AlarmManager : public QObject {
    Q_OBJECT

public:
    explicit AlarmManager(ChannelManager* channelManager, QObject *parent = nullptr);
    ~AlarmManager();

    // 规则管理
    QString addRule(const AlarmRule& rule);
    bool updateRule(const QString& ruleId, const AlarmRule& rule);
    bool removeRule(const QString& ruleId);
    AlarmRule getRule(const QString& ruleId) const;
    QList<AlarmRule> getAllRules() const;
    void clearAllRules();

    // 规则启用/禁用
    bool enableRule(const QString& ruleId, bool enable);

    // 事件管理
    QList<AlarmEvent> getActiveAlarms() const;
    QList<AlarmEvent> getAlarmHistory(const QDateTime& start, const QDateTime& end) const;
    AlarmEvent getAlarmEvent(const QString& eventId) const;

    // 报警确认
    bool acknowledgeAlarm(const QString& eventId, const QString& acknowledgedBy = QString());

    // 报警清除（手动）
    bool clearAlarm(const QString& eventId);

    // 统计
    int getActiveAlarmCount() const;
    int getAlarmCount(AlarmPriority priority) const;
    int getTotalAlarmCount() const;

    // 配置
    bool loadConfig(const QString& filename);
    bool saveConfig(const QString& filename) const;
    QJsonObject toJson() const;
    void fromJson(const QJsonObject& json);

signals:
    // 新报警触发
    void alarmTriggered(const AlarmEvent& event);

    // 报警确认
    void alarmAcknowledged(const QString& eventId);

    // 报警清除
    void alarmCleared(const QString& eventId);

    // 规则变化
    void ruleAdded(const QString& ruleId);
    void ruleUpdated(const QString& ruleId);
    void ruleRemoved(const QString& ruleId);

private slots:
    // 数据更新监听
    void onDataUpdated(const QString& tagName, const DataPoint& point);

    // 连接状态监听
    void onCollectorConnectionChanged(const QString& collectorName, bool connected);

private:
    // 检查报警条件
    void checkAlarmConditions(const QString& channelName, const QString& tagName, const DataPoint& point);

    // 触发报警
    void triggerAlarm(const AlarmRule& rule, const QString& channelName,
                      const QString& tagName, const QVariant& value);

    // 自动清除报警
    void autoClearAlarm(const QString& ruleId);

    // 生成报警消息
    QString generateAlarmMessage(const AlarmRule& rule, const QVariant& value) const;

    // 连接通道信号
    void connectChannelSignals(Channel* channel);

private:
    ChannelManager* m_channelManager;

    // 规则
    QList<AlarmRule> m_rules;
    mutable QMutex m_rulesMutex;

    // 活动报警
    QList<AlarmEvent> m_activeAlarms;
    QMap<QString, AlarmEvent> m_activeAlarmsMap;  // ruleId -> 最新活动报警

    // 历史报警（最近1000条）
    QList<AlarmEvent> m_alarmHistory;
    int m_maxHistorySize;

    mutable QMutex m_alarmsMutex;

    // 延时检查缓存（避免瞬时抖动）
    struct DelayEntry {
        QDateTime firstTriggerTime;
        QVariant value;
    };
    QMap<QString, DelayEntry> m_delayCache;  // ruleId -> DelayEntry
};

} // namespace ModbusPlexLink

#endif // ALARMMANAGER_H
